import { ref, onUnmounted, watch, h, unref, toRaw } from 'vue';
import type { WatchStopHandle } from 'vue';
import { Tag } from 'ant-design-vue';

import type { DynamicProps } from '#/utils';
import type { FormActionType } from '@/components/Form';

import { FetchParams } from '@/components/Table';
import type { PaginationProps } from '@/components/Table/src/types/pagination';
import { FormModeEnum } from '@/enums/formEnum';

import { formatToDate } from '@/utils/dateUtil';
import { isProdMode } from '@/utils/env';
import Icon from '@/components/Icon/Icon.vue';
import { isBoolean, isString, isNumber, isArray } from '@/utils/is';
import { getDynamicProps } from '@/utils';
import { error } from '@/utils/log';
import { expandAndToString } from '@/utils/common';
import type { Key } from 'ant-design-vue/lib/table/interface';

import type { AdTableProps, AdColumn, AdTableActionType } from '../types/adTable';

type Props = Partial<DynamicProps<AdTableProps>>;

type UseTableMethod = AdTableActionType & {
  getForm: () => FormActionType;
};

/**
 * 使用高级表格
 * @param tableProps 表格选项
 * @returns 高级表格对象
 */
export function useAdTable(tableProps?: Props): [
  (instance: AdTableActionType, formInstance: UseTableMethod) => void,
  AdTableActionType & {
    getForm: () => FormActionType;
  },
] {
  const tableRef = ref<Nullable<AdTableActionType>>(null);
  const loadedRef = ref<Nullable<boolean>>(false);
  const formRef = ref<Nullable<UseTableMethod>>(null);

  let stopWatch: WatchStopHandle;

  if (tableProps && tableProps.columns) {
    tableProps.columns = renderAdColumns(tableProps.columns as AdColumn[]);
  }

  const defaultTableProps: Props = {
    //#region BasicTableProps
    rowKey: 'Id', //行Key
    autoCreateKey: false, //自动创建行key
    size: 'default', //表格密度 'default' | 'middle' | 'small' | 'large';
    showTableSetting: true, // 显示表格设置工具
    tableSetting: { redo: true, size: true, setting: true, fullScreen: true }, //表格设置项
    canResize: true, // 自适应高度
    canColDrag: false, // 是否可拖拽列
    bordered: false, // 是否显示表格边框
    striped: false, // 斑马线
    ellipsis: true, // 显示...
    showIndexColumn: true, // 显示序号
    useSearchForm: true, // 是否使用搜索表单

    clearSelectOnPageChange: false, //换行是否清楚选中
    clickToRowSelect: true, // 行选中
    //rowSelection: { type: 'checkbox', preserveSelectedRowKeys: true }, // 行选中类型 radio | checkbox
    //#endregion
    immediate: true, // 是否立即执行
    columns: [], // 表格列配置
  };

  tableProps = {
    ...defaultTableProps,
    ...tableProps,
  };

  /** 注册 */
  function register(instance: AdTableActionType, formInstance: UseTableMethod) {
    isProdMode() &&
      onUnmounted(() => {
        tableRef.value = null;
        loadedRef.value = null;
      });

    if (unref(loadedRef) && isProdMode() && instance === unref(tableRef)) return;

    tableRef.value = instance;
    formRef.value = formInstance;
    tableProps && instance.setProps(getDynamicProps(tableProps));
    loadedRef.value = true;

    stopWatch?.();

    stopWatch = watch(
      () => tableProps,
      () => {
        tableProps && instance.setProps(getDynamicProps(tableProps));
      },
      {
        immediate: true,
        deep: true,
      },
    );
  }

  /** 获取高级表格实例 */
  function getTableInstance(): AdTableActionType {
    const table = unref(tableRef);
    if (!table) {
      error('尚未获取表实例，请在执行表操作时确保表已呈现！');
    }
    return table as AdTableActionType;
  }

  const methods: AdTableActionType & {
    getForm: () => FormActionType;
  } = {
    /** 打开详情表单 */
    openDetailForm: (formMode: FormModeEnum, record?: Recordable<any>) => {
      getTableInstance().openDetailForm(formMode, record);
    },
    reload: async (opt?: FetchParams) => {
      return await getTableInstance().reload(opt);
    },
    // @ts-ignore
    setProps: (props: Partial<AdTableProps>) => {
      getTableInstance().setProps(props);
    },
    redoHeight: () => {
      getTableInstance().redoHeight();
    },
    setSelectedRows: (rows: Recordable[]) => {
      return toRaw(getTableInstance().setSelectedRows(rows));
    },
    setLoading: (loading: boolean) => {
      getTableInstance().setLoading(loading);
    },
    getDataSource: () => {
      return getTableInstance().getDataSource();
    },
    getRawDataSource: () => {
      return getTableInstance().getRawDataSource();
    },
    /** 获取搜索信息 */
    getSearchInfo: () => {
      return getTableInstance().getSearchInfo();
    },
    getColumns: ({ ignoreIndex = false }: { ignoreIndex?: boolean } = {}) => {
      const columns = getTableInstance().getColumns({ ignoreIndex }) || [];
      return toRaw(columns);
    },
    // @ts-ignore
    setColumns: (columns: AdColumn[]) => {
      getTableInstance().setColumns(columns);
    },
    setTableData: (values: any[]) => {
      return getTableInstance().setTableData(values);
    },
    setPagination: (info: Partial<PaginationProps>) => {
      return getTableInstance().setPagination(info);
    },
    deleteSelectRowByKey: (key: string | number) => {
      getTableInstance().deleteSelectRowByKey(key);
    },
    getSelectRowKeys: () => {
      return toRaw(getTableInstance().getSelectRowKeys());
    },
    getSelectRows: () => {
      return toRaw(getTableInstance().getSelectRows());
    },
    clearSelectedRowKeys: () => {
      getTableInstance().clearSelectedRowKeys();
    },
    setSelectedRowKeys: (keys: (string | number)[]) => {
      getTableInstance().setSelectedRowKeys(keys);
    },
    getPaginationRef: () => {
      return getTableInstance().getPaginationRef();
    },
    getSize: () => {
      return toRaw(getTableInstance().getSize());
    },
    updateTableData: (index: number, key: string, value: any) => {
      return getTableInstance().updateTableData(index, key, value);
    },
    updateTableDataRecord: (rowKey: string | number, record: Recordable) => {
      return getTableInstance().updateTableDataRecord(rowKey, record);
    },
    deleteTableDataRecord: (rowKey: string | number | (string | number)[]) => {
      return getTableInstance().deleteTableDataRecord(rowKey);
    },
    insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => {
      return getTableInstance().insertTableDataRecord(record, index);
    },
    findTableDataRecord: (rowKey: string | number) => {
      return getTableInstance().findTableDataRecord(rowKey);
    },
    getRowSelection: () => {
      return toRaw(getTableInstance().getRowSelection());
    },
    getCacheColumns: () => {
      return toRaw(getTableInstance().getCacheColumns());
    },
    getForm: () => {
      return unref(formRef) as unknown as FormActionType;
    },
    setShowPagination: async (show: boolean) => {
      getTableInstance().setShowPagination(show);
    },
    getShowPagination: () => {
      return toRaw(getTableInstance().getShowPagination());
    },
    expandAll: () => {
      getTableInstance().expandAll();
    },
    collapseAll: () => {
      getTableInstance().collapseAll();
    },
    expandRows: (keys: Key[]) => {
      getTableInstance().expandRows(keys);
    },
    collapseRows: (keys: Key[]) => {
      getTableInstance().collapseRows(keys);
    },
    scrollTo: (pos: string) => {
      getTableInstance().scrollTo(pos);
    },
  };

  return [register, methods];
}

//#region 渲染高级表格列集合
/**
 * 渲染高级列集合
 * @param columns 列集合
 * @returns 处理后的高级列集合
 */
export function renderAdColumns(columns: AdColumn[]): AdColumn[] {
  const data: AdColumn[] = [];

  columns.forEach((item) => {
    const newItem = { ...item };
    // 默认可拖动调整宽度
    if (newItem.resizable === undefined || newItem.resizable === null) {
      newItem.resizable = true;
    }
    // if (!newItem.customHeaderCell) {
    //   newItem.customHeaderCell = ({ column }) => {
    //     column.align = 'center';
    //   };
    // }

    // newItem.customRender = (value, row, index) => {
    //   //表体的数据列样式
    //   console.log(value, row, index); //本列的值,所有行数据包括本列,第几列
    //   const obj = {
    //     children: value,
    //     attrs: {},
    //   };
    //   obj.attrs.align = 'right';
    //   return obj;
    // };
    //渲染列样式
    switch (newItem.dataType) {
      case 'enum':
        if (!newItem.align) {
          newItem.align = 'center';
        }
        // if (
        //   (!newItem.enumData || newItem.enumData?.length <= 0) &&
        //   newItem.editComponent === 'ApiSelect' &&
        //   newItem.editComponentProps?.api
        // ) {
        //   //TODO:这个地方远程请求是有问题的（异步原因），需要在调用组件前手动获取值后赋值
        //   const apiFunction = newItem.editComponentProps.api;
        //   if (isFunction(apiFunction)) {
        //     apiFunction(newItem.editComponentProps?.params).then((res: EnumSchema[]) => {
        //       newItem.enumData = res;
        //     });
        //   }
        // }
        if (!newItem.customRender && newItem.enumData && newItem.enumData.length > 0) {
          newItem.customRender = ({ text }) => {
            if (isNumber(text) || isString(text)) {
              const currentEnumData = newItem.enumData?.find((m) => {
                return m.value === text;
              });
              if (!currentEnumData) {
                return text;
              }
              if (!currentEnumData.tag) {
                return currentEnumData.label;
              }
              return h(
                Tag,
                {
                  closable: false,
                  color: currentEnumData.tagColor,
                  icon: currentEnumData.tagIcon,
                },
                { default: () => currentEnumData.label || currentEnumData.value },
              );
            }
          };
        }
        break;
      case 'integer':
      case 'number':
      case 'quantity':
      case 'price':
      case 'amount':
      case 'rate':
      case 'percentage':
      case 'measure':
        if (!newItem.align) {
          newItem.align = 'right';
        }
        break;
      case 'string':
      case 'text':
      case 'email':
      case 'mobile':
      case 'url':
      case 'ipv4':
      case 'ipv6':
      case 'idcard':
        if (!newItem.align) {
          newItem.align = 'left';
        }
        break;
      case 'password':
        if (!newItem.align) {
          newItem.align = 'left';
        }
        if (!newItem.format) {
          newItem.format = (_text: string, _record: Recordable, _index: number) => '******';
        }
        break;
      case 'guid':
        if (!newItem.align) {
          newItem.align = 'center';
        }
        break;
      case 'boolean':
        if (!newItem.align) {
          newItem.align = 'center';
        }
        if (!newItem.customRender) {
          newItem.customRender = ({ text }) => {
            if (isBoolean(text)) {
              return h(Icon, {
                icon: text ? 'ant-design:check-outlined' : 'ant-design:close-outlined',
                color: text ? '#48a5ea' : '#e25e37',
              });
            }
          };
        }
        break;
      case 'datetime':
      case 'date':
      case 'time':
        if (!newItem.align) {
          newItem.align = 'center';
        }
        const DATE_FORMAT_PREFIX = 'date|';
        let dateFormat = '';
        if (!newItem.format) {
          dateFormat =
            item.dataType === 'datetime'
              ? 'YYYY-MM-DD HH:mm:ss'
              : item.dataType === 'date'
                ? 'YYYY-MM-DD'
                : 'HH:mm:ss';
        } else if (isString(newItem.format)) {
          dateFormat = newItem.format.replace(DATE_FORMAT_PREFIX, '');
        }
        if (dateFormat !== undefined && dateFormat !== null && dateFormat !== '') {
          newItem.format = (text: string, _record: Recordable, _index: number) =>
            formatToDate(text, dateFormat);
        }
        break;
      case 'array':
        if (!newItem.format) {
          newItem.format = (text: string, _record: Recordable, _index: number) =>
            isArray(text) ? expandAndToString(text as unknown as any[]) : text;
        }
        break;
    }
    data.push(newItem);
  });

  return data;
}
//#endregion
